package org.dev.hi.hiui.slider

import android.content.Context
import android.content.res.ColorStateList
import android.graphics.Color
import android.graphics.drawable.Drawable
import android.util.AttributeSet
import android.util.TypedValue
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.LinearLayout
import android.widget.TextView
import androidx.annotation.LayoutRes
import androidx.core.content.ContextCompat
import androidx.recyclerview.widget.*
import kotlinx.android.synthetic.main.hi_slider_menu_item.view.*
import org.dev.hi.hiui.R
import org.dev.hi.hiui.item.HiViewHolder

/**
 * Author WenPing
 * CreateTime 2021/6/12.
 * Description:上下滑动的slider
 */
class HiSliderView @JvmOverloads constructor(
    context: Context,
    attributeSet: AttributeSet? = null,
    defStyle: Int = 0
) : LinearLayout(context, attributeSet, defStyle) {

    // MenuItemAttr 实例，从解析属性后获得
    private var menuItemAttr: MenuItemAttr

    // 左侧菜单的宽度和高度
    private val MENU_WIDTH = applyUnit(TypedValue.COMPLEX_UNIT_DIP, 100f)
    private val MENU_HEIGHT = applyUnit(TypedValue.COMPLEX_UNIT_DIP, 45f)

    // 左侧菜单的text大小
    private val MENU_TEXT_SIZE = applyUnit(TypedValue.COMPLEX_UNIT_SP, 14f)

    // 选中和未选中的文字颜色
    private val TEXT_COLOR_NORMAL = Color.parseColor("#666666")
    private val TEXT_COLOR_SELECTED = Color.parseColor("#DD3127")

    // 被选中的背景和未选中的背景
    private val BG_COLOR_NORMAL = Color.parseColor("#F7F8F9")
    private val BG_COLOR_SELECT = Color.parseColor("#ffffff")

    // 左侧菜单的item布局
    private val MENU_ITEM_LAYOUT_RES_ID = R.layout.hi_slider_menu_item

    // 右侧内容部分的布局
    private val CONTENT_ITEM_LAYOUT_RES_ID = R.layout.hi_slider_content_item

    // 左侧和右侧都各自用一个recyclerview来加载
    private val menuView = RecyclerView(context)
    private val contentView = RecyclerView(context)

    private fun applyUnit(unit: Int, value: Float): Int {
        return TypedValue.applyDimension(unit, value, context.resources.displayMetrics).toInt()
    }


    /**
     * 解析属性
     */
    init {
        /**
         * 解析属性
         */
        menuItemAttr = parseMenuItemAttribute(attributeSet)

        //rootView 水平的线性布局 给布局里分别添加左侧的菜单view和右侧的内容view

        orientation = HORIZONTAL

        menuView.run {
            layoutParams = LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT)
            // Never allow a user to over-scroll this view
            overScrollMode = View.OVER_SCROLL_NEVER
            // 没有滑动的动画
            itemAnimator = null

        }
        contentView.run {

            layoutParams = LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT)

            overScrollMode = View.OVER_SCROLL_NEVER
            itemAnimator = null

        }

        addView(menuView)

        addView(contentView)

    }

    private fun parseMenuItemAttribute(attributeSet: AttributeSet?): MenuItemAttr {
        val typedArray =
            context.obtainStyledAttributes(attributeSet, R.styleable.HiSliderView)
        val menuItemWidth =
            typedArray.getDimensionPixelOffset(R.styleable.HiSliderView_menuItemWidth, MENU_WIDTH)
        val menuItemHeight =
            typedArray.getDimensionPixelOffset(R.styleable.HiSliderView_menuItemHeight, MENU_HEIGHT)
        val menuTextSize = typedArray.getDimensionPixelOffset(
            R.styleable.HiSliderView_menuItemTextSize,
            MENU_TEXT_SIZE
        )
        val menuSelectedTextSize = typedArray.getDimensionPixelOffset(
            R.styleable.HiSliderView_menuItemSelectTextSize,
            MENU_TEXT_SIZE
        )

        // HiSliderView_menuItemTextColor 引用类型
        val menuItemTextColor =
            typedArray.getColorStateList(R.styleable.HiSliderView_menuItemTextColor)
                ?: generateColorStateList()

        // HiSliderView_menuItemIndicator 引用类型 显示的是一个drawable
        val menuItemIndicator = typedArray.getDrawable(R.styleable.HiSliderView_menuItemIndicator)
            ?: ContextCompat.getDrawable(context, R.drawable.shape_hi_slider_indicator)
        // HiSliderView_menuItemBackgroundColor color属性
        val menuItemBackgroundColor =
            typedArray.getColor(R.styleable.HiSliderView_menuItemBackgroundColor, BG_COLOR_NORMAL)
        // HiSliderView_menuItemSelectBackgroundColor color属性
        val menuItemBackgroundSelectColor = typedArray.getColor(
            R.styleable.HiSliderView_menuItemSelectBackgroundColor,
            BG_COLOR_SELECT
        )

        typedArray.recycle()

        return MenuItemAttr(
            menuItemWidth,
            menuItemHeight,
            menuItemTextColor,
            menuItemBackgroundSelectColor,
            menuItemBackgroundColor,
            menuTextSize,
            menuSelectedTextSize,
            menuItemIndicator
        )
    }

    /**
     * 颜色选中和未选中颜色 colorList
     */
    private fun generateColorStateList(): ColorStateList {
        // 创建一个数组，是一个IntArray size为2
        val states = Array(2) { IntArray(2) }
        // 两个整型数组
        val colors = IntArray(2)
        // index 0 选中，index 1 未选中
        colors[0] = TEXT_COLOR_SELECTED
        colors[1] = TEXT_COLOR_NORMAL

        states[0] = IntArray(1) { android.R.attr.state_selected }
        states[1] = IntArray(1)
        return ColorStateList(states, colors)
    }


    data class MenuItemAttr(
        val width: Int,
        val height: Int,
        val TextColor: ColorStateList,
        val selectBackgroundColor: Int,
        val normalBackgroundColor: Int,
        val textSize: Int,
        val selectTextSize: Int,
        val indicator: Drawable?
    )


    fun bindContentView(
        layoutRes: Int = CONTENT_ITEM_LAYOUT_RES_ID,
        itemCount: Int,
        itemDecoration: RecyclerView.ItemDecoration?,
        layoutManager: RecyclerView.LayoutManager,
        onBindView: (HiViewHolder, Int) -> Unit,
        onItemclick: (HiViewHolder, Int) -> Unit
    ) {
        //如果 contentView的layoutManager是空的
        if (contentView.layoutManager == null) {
            contentView.layoutManager = layoutManager
            contentView.adapter = ContentAdapter(layoutRes)

            itemDecoration?.let {
                contentView.addItemDecoration(itemDecoration)
            }
        }

        val contentAdapter = contentView.adapter as ContentAdapter
        // 更新data的size以及绑定和点击的回调
        contentAdapter.update(itemCount, onBindView, onItemclick)
        // notify一次
        contentAdapter.notifyDataSetChanged()
        // 滑动最开始的位置
        contentView.scrollToPosition(0)
    }

    /**
     * 创建右侧的内容的适配器
     */
    inner class ContentAdapter(val layoutRes: Int) : RecyclerView.Adapter<HiViewHolder>() {

        /*
         * 定义item的点击函数，带有两个参数，无返回值
         */
        private lateinit var onItemClick: (HiViewHolder, Int) -> Unit

        /*
         * 定义绑定view的函数，无返回值
         */
        private lateinit var onBindView: (HiViewHolder, Int) -> Unit

        private var count = 0

        override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): HiViewHolder {

            val itemView = LayoutInflater.from(context)
                .inflate(layoutRes, parent, false)

            // 以下是 设置item的尺寸参数

            // 宽度
            val remainSpace = width - paddingLeft - paddingRight - menuItemAttr.width

            val layoutManager = (parent as RecyclerView).layoutManager
            // 每行占据的数量
            var spanCount = 0

            // grid类
            if (layoutManager is GridLayoutManager) {
                spanCount = layoutManager.spanCount
                // 瀑布流
            } else if (layoutManager is StaggeredGridLayoutManager) {
                spanCount = layoutManager.spanCount
            }

            if (spanCount > 0) {
                val itemWidth = remainSpace / spanCount
                //宽度和高度一致；创建contenv itemView 设置它的尺寸参数的原因：
                //防止图片未加载出来时，列表滑动，上下闪动的效果
                itemView.layoutParams = RecyclerView.LayoutParams(itemWidth, itemWidth)
            }
            return HiViewHolder(itemView)
        }

        override fun getItemCount(): Int {
            return count
        }

        override fun onBindViewHolder(holder: HiViewHolder, position: Int) {
            // 传入参数 实现接口回调
            onBindView(holder, position)
            holder.itemView.setOnClickListener {
                onItemClick(holder, position)
            }
        }

        fun update(
            itemCount: Int,
            onBindView: (HiViewHolder, Int) -> Unit,
            onItemclick: (HiViewHolder, Int) -> Unit
        ) {
            this.count = itemCount
            this.onBindView = onBindView
            this.onItemClick = onItemclick
        }
    }

    fun bindMenuView(
        layoutRes: Int = MENU_ITEM_LAYOUT_RES_ID,
        itemCount: Int,
        onBindView: (HiViewHolder, Int) -> Unit,
        onItemclick: (HiViewHolder, Int) -> Unit
    ) {
        menuView.run {
            layoutManager = LinearLayoutManager(context, LinearLayoutManager.VERTICAL, false)
            adapter = MenuAdapter(layoutRes, itemCount, onBindView, onItemclick)
        }
    }

    /**
     * 创建左侧菜单列表的适配器
     */
    inner class MenuAdapter(
        val layoutRes: Int,
        val count: Int,
        val onBindView: (HiViewHolder, Int) -> Unit,
        val onItemclick: (HiViewHolder, Int) -> Unit
    ) : RecyclerView.Adapter<HiViewHolder>() {
        // 上一次选中的item的为哦哦之
        private var lastSelectedIndex = 0

        private var currentSelectedIndex = 0

        override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): HiViewHolder {
            val itemView = LayoutInflater.from(context)
                .inflate(layoutRes, parent, false)
            val params = RecyclerView.LayoutParams(menuItemAttr.width, menuItemAttr.height)

            itemView.run {
                layoutParams = params
                setBackgroundColor(menuItemAttr.normalBackgroundColor)
                findViewById<TextView>(R.id.menu_item_title)?.setTextColor(menuItemAttr.TextColor)
                findViewById<ImageView>(R.id.menu_item_indicator).setImageDrawable(menuItemAttr.indicator)
            }
            return HiViewHolder(itemView)
        }

        override fun getItemCount(): Int {
            return count
        }

        override fun onBindViewHolder(holder: HiViewHolder, position: Int) {
            holder.itemView
                .setOnClickListener {
                    currentSelectedIndex = position
                    //更新选中状态
                    notifyItemChanged(position)
                    //把前一次的还原
                    notifyItemChanged(lastSelectedIndex)
                    //为什么不用 applyItemAttr 更新当前选中的数据？
                    //上次选中效果不会立刻被更新掉，避免出现两个选中效果->用两个notifyxxx
                }

            if (currentSelectedIndex == position) {
                onItemclick(holder, position)
                lastSelectedIndex = currentSelectedIndex
            }
            applyItemAttr(position, holder)
            onBindView(holder, position)

        }

        private fun applyItemAttr(position: Int, holder: HiViewHolder) {
            val selected = position == currentSelectedIndex
            val titleView: TextView? = holder.itemView.menu_item_title
            val indicator: ImageView? = holder.itemView.menu_item_indicator
            // 选中则显示indicator 未选中则不显示
            indicator?.visibility = if (selected) View.VISIBLE else View.GONE
            titleView?.setTextSize(
                TypedValue.COMPLEX_UNIT_PX,
                if (selected) menuItemAttr.selectTextSize.toFloat() else menuItemAttr.textSize.toFloat()
            )
            holder.itemView.setBackgroundColor(
                if (selected) menuItemAttr.selectBackgroundColor else menuItemAttr.normalBackgroundColor
            )
            titleView?.isSelected = selected
        }
    }

}